package com.ccc.boot.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ccc.boot.exception.BusinessException;
import com.ccc.boot.pojo.Query;
import com.ccc.boot.redis.constant.RedisConstant;
import com.ccc.boot.redis.util.RedisUtils;
import com.ccc.boot.response.ResponseCode;
import com.ccc.boot.system.entity.SysDictInfo;
import com.ccc.boot.system.mapper.SysDictInfoMapper;
import com.ccc.boot.system.service.SysDictInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 〈数据字典从表——服务层〉
 *
 * @author superC
 * @version 0.1.0
 * @date 2022/3/30
 */
@Service
public class SysDictInfoServiceImpl implements SysDictInfoService {

    @Autowired
    private SysDictInfoMapper sysDictInfoMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public boolean add(SysDictInfo data) {
        // 清除redis缓存数据
        deleteDictCache(data.getDictId());

        int count = sysDictInfoMapper.selectCount(new QueryWrapper<>(data));
        if (count > 0) {
            throw new BusinessException(ResponseCode.DATA_ALREADY_EXISTED);
        }
        return sysDictInfoMapper.insert(data) > 0;
    }

    @Override
    public boolean delete(SysDictInfo data) {
        // 删除redis缓存数据
        deleteDictCache(data.getDictId());

        LambdaQueryWrapper<SysDictInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDictInfo::getDictId, data.getDictId());
        wrapper.eq(SysDictInfo::getCode, data.getCode());
        return sysDictInfoMapper.delete(wrapper) > 0;
    }

    @Override
    public boolean update(SysDictInfo data) {
        // 清除redis缓存数据
        deleteDictCache(data.getDictId());

        LambdaUpdateWrapper<SysDictInfo> wrapper = new LambdaUpdateWrapper();
        // 条件
        wrapper.eq(SysDictInfo::getDictId, data.getDictId());
        wrapper.eq(SysDictInfo::getCode, data.getCode());
        // 修改字段
        wrapper.set(SysDictInfo::getName, data.getName());
        wrapper.set(SysDictInfo::getMemo, data.getMemo());
        return sysDictInfoMapper.update(data, wrapper) > 0;
    }

    @Override
    public void deleteDictCache(String dictId) {
        String key = getRedisKey(dictId);
        if (redisUtils.hasKey(key)) {
            redisUtils.del(key);
        }
    }

    @Override
    public void deleteAllDictCache(Set<String> dictIds) {
        dictIds.forEach(dictId -> {
            deleteDictCache(dictId);
        });
    }

    @Override
    public IPage<SysDictInfo> page(Query query) {
        Page<SysDictInfo> page = new Page<>(query.getCurrent(), query.getSize());
        LambdaQueryWrapper<SysDictInfo> queryWrapper = new LambdaQueryWrapper<>();
        // 全局进行模糊查询
        query.forEach((column, value) -> {
            if ("dict_id".equals(column)) {
                queryWrapper.eq(SysDictInfo::getDictId, value);
            }
            if ("condition".equals(column)) {
                queryWrapper.and(wrapper -> {
                    wrapper.like(SysDictInfo::getCode, value)
                            .or()
                            .like(SysDictInfo::getName, value);
                });
            }
        });
        return sysDictInfoMapper.selectPage(page, queryWrapper);
    }

    @Override
    public List<SysDictInfo> getList(SysDictInfo sysDictInfo) {
        QueryWrapper<SysDictInfo> wrapper = new QueryWrapper<>(sysDictInfo);
        List<SysDictInfo> list = sysDictInfoMapper.selectList(wrapper);
        if (null == list || list.size() == 0) {
            throw new BusinessException(ResponseCode.RESULT_DATA_NONE);
        }
        return list;
    }

    /**
     * 根据dictIds,获取数据字典
     *
     * @param dictIds
     * @return {@link Map< String, Map< String, Object>>}
     * @date 2022/4/11 14:19
     * @author superC
     */
    @Override
//    @Cacheable(value = RedisConstant.SYS_DICT_DATA_MULTIPLE, key = "#dictIds", unless = "#result.empty")
    public Map<String, Map<String, Object>> getDictData(String dictIds) {
        Map<String, Map<String, Object>> resultMap = new HashMap<>();
        String[] ids = dictIds.split(",");
        for (String id : ids) {
            if (StrUtil.isEmpty(id)) {
                continue;
            }
            // 获取id对应的数据字典
            Map<String, Object> codeMap = selectMap(id);
            if (codeMap.isEmpty()) {
                continue;
            }
            resultMap.put(id, codeMap);
        }
        return resultMap;
    }

    /**
     * 根据关键字,获取数据字典
     *
     * @param dictId 关键字
     * @return {@link Map< String, Object>}
     * @date 2022/4/11 14:18
     * @author superC
     */
    @Override
    @Cacheable(value = RedisConstant.SYS_DICT_DATA, key = "#dictId", unless = "#result.empty")
    public Map<String, Object> selectMap(String dictId) {
        /*
            从数据库获取数据
         */
        LambdaQueryWrapper<SysDictInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysDictInfo::getDictId, dictId);
        List<SysDictInfo> codeList = sysDictInfoMapper.selectList(wrapper);
        if (codeList.isEmpty()) {
            return new HashMap<>();
        }
        // list转map
        Map<String, Object> codeMap = codeList.stream().collect(
                Collectors.toMap(SysDictInfo::getCode, SysDictInfo::getName));



        return codeMap;
    }

    private String getRedisKey(String dictId) {
        return RedisConstant.SYS_DICT_DATA + dictId;
    }

}
